package demo.issuetracker.dao.jpa;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.persistence.Query;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import demo.issuetracker.dao.jpa.JpaUser;

import demo.issuetracker.dao.IssueDao;
import demo.issuetracker.entity.Issue;

@Component("issueDao")
@Repository
@Transactional
public class JpaIssueDao extends AbstractJpaDao<Issue> implements IssueDao {
    @Override
    public void create(Issue issue) {
        Object pk = issue.primaryKey();
        if (pk == null) {
            pk = generatePrimaryKey();
            
            issue.setId((String) pk);
        }

        em.persist(issue);
    }

    @PostConstruct
    public void init() {
        // initialize the db with some initial data
    }

    /**
     * The "Create" or "Update" semantics of "CRUD"
     */
    public void createOrUpdate(Issue issue) {
        if (issue.primaryKey() == null) {
            create(issue);
            return;
        }

        em.merge(issue);
    }

    /**
     * Find by Primary key
     * 
     * The "read" operation of CRUD
     */
    public Issue findByPrimaryKey(String key) {
        if (key == null) {
            return null;
        }
        return em.find(JpaIssue.class, key);
    }


    @Override
    public void delete(Issue issue) {
        em.remove(issue);
    }

    @Override
    public void update(Issue issue) {
        em.merge(issue);
    }


    /**
     * All Issues. Display all Issues in the system.
     * 
     * The "read" operation of CRUD
     */
    public List<Issue> findIssueList(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaIssue issue " /* where issue.field1=:param1 and issue.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaIssue> issueList = qry.getResultList();

        return new ArrayList<Issue>(issueList);
    }

    /**
     * My Team's Issues. All issues belonging to user's team
     * 
     * $fact.text
     * 
     * The "read" operation of CRUD
     */
    public List<Issue> findTeamIssues(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaIssue issue " /* where issue.field1=:param1 and issue.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaIssue> issueList = qry.getResultList();

        return new ArrayList<Issue>(issueList);
    }
    
    /**
     * Issue. The issue viewed on this page
     * 
         * The "read" operation of CRUD
     */
    public Issue getIssue(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaIssue issue " /* where issue.field1=:param1 and issue.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaIssue> issueList = qry.getResultList();

        if (issueList.size() == 0) {
            return null;
        }

        if (issueList.size() == 1) {
            return issueList.get(0);
        }

        throw new RuntimeException(
                "More than one Issue found. Please contact the administrator.");    
    }

    @Override
    public Issue newInstance() {
        Issue issue = new JpaIssue();
        
        issue.setAttachment(UploadedFileDao.newInstance());
        return issue;
    }

    private Object generatePrimaryKey() {
        return UUID.randomUUID().toString();
    }
    
    public <K> List<Issue> findBy(String name, K value) {
        return queryBySingleArgument("from JpaIssue issue where issue." + name + " = :value", name, value);
    }
}// clickframes::version=3654349564::clickframes